﻿
using System.Collections.Generic;
using System.IO;
using System.Text;
using System;
using Newtonsoft.Json;
using System.Linq;
using NWMES.Model;
using BaseUtils.Utils;
using System.Xml.Linq;
using BaseUtils.Logger;

namespace NWMES.Mes
{
    public class MESBaseService : MesBaseEntity
    {
        private readonly string MesFilePath  = AppDomain.CurrentDomain.BaseDirectory + "MESCFG.ini";
        public static IniHelper IniUtil ;
      
        public string InterfaceName { get; set; }

        public string Mtehod { get; set; }

        /// <summary>
        /// 更新mes请求参数，
        /// </summary>
        /// <param name="ApiName"></param>
        /// <param name="mesBaseEntity"></param>
        public void UpdateMesRequestParams(string ApiSection, MesBaseEntity mesBaseEntity)
        {
            if (IniUtil==null)
            {
                IniUtil = new IniHelper(MesFilePath);
            }
            IniUtil.WriteValue(ApiSection, "Url", mesBaseEntity.Url);
            IniUtil.WriteValue(ApiSection, "UserName", mesBaseEntity.UserName);
            IniUtil.WriteValue(ApiSection, "Password", mesBaseEntity.Password);
            IniUtil.WriteValue(ApiSection, "User", mesBaseEntity.User);
            IniUtil.WriteValue(ApiSection, "Timeout", mesBaseEntity.Timeout.ToString());
            IniUtil.WriteValue(ApiSection, "Site", mesBaseEntity.Site);
            IniUtil.WriteValue(ApiSection, "ActivityId", mesBaseEntity.ActivityId);
            IniUtil.WriteValue(ApiSection, "Operation", mesBaseEntity.Operation);
            IniUtil.WriteValue(ApiSection, "OperationRevision", "\"" + mesBaseEntity.OperationRevision + "\"");
            IniUtil.WriteValue(ApiSection, "Resource", mesBaseEntity.Resource);
            IniUtil.WriteValue(ApiSection, "DcGroup", mesBaseEntity.DcGroup);
            IniUtil.WriteValue(ApiSection, "DcGroupRevision", "\"" + mesBaseEntity.DcGroupRevision + "\"");
            IniUtil.WriteValue(ApiSection, "ModeProcessSFC", mesBaseEntity.ModeProcessSFC);
            IniUtil.WriteValue(ApiSection, "dcGroupSequence", mesBaseEntity.dcGroupSequence);
            IniUtil.WriteValue(ApiSection, "dcMode", mesBaseEntity.dcMode);
            IniUtil.WriteValue(ApiSection, "material", mesBaseEntity.material);
            IniUtil.WriteValue(ApiSection, "materialRevision", "\"" + mesBaseEntity.materialRevision + "\"");
            //IniHelper.IniWriteValue(ApiSection, "remark", "\"" + mesBaseEntity.remark + "\"\r\n", MESCFGPath);

            RefreshConfig();
        }

        static object mesLogLock = new object();

        /// <summary>
        /// 报错MES日志
        /// </summary>
        /// <param name="InterfaceName"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        public static bool SaveMesLog(string InterfaceName, MesResult log)
        {
            var cols = new List<string>() {
            "传参",
            "调用开始时间",
            "调用结束时间",
            "返回",
            "Code",
            "Message",
            };

            lock (mesLogLock)
            {
                bool saveComp = false;
                try
                {
                    string dirPath = Path.Combine(DefaultLogFileSavePath, InterfaceName);

                    if (!Directory.Exists(dirPath))
                    {
                        Directory.CreateDirectory(dirPath);
                    }
                    var fullPath = Path.Combine(dirPath, $"{DateTime.Now:yyyyMMdd}.csv");
                    if (!File.Exists(fullPath))
                    {
                        var titleLine = string.Join(",", cols) + "\r\n";

                        File.AppendAllText(fullPath, titleLine, Encoding.GetEncoding("GB2312"));
                    }

                    var paraList = new List<string>() {
                        GetObjCsvStr(log.Request),
                        log.BeginTime.ToString(),
                        log.EndTime.ToString(),
                        GetObjCsvStr(log.ResponeJson),
                        log.Code.ToString(),
                        GetObjCsvStr(log.Message)
                    };

                    var dataLine = string.Join(",", paraList.Select(a => a)) + "\r\n";

                    File.AppendAllText(fullPath, dataLine, Encoding.GetEncoding("GB2312"));
                    saveComp = true;
                }
                catch (IOException ex)
                {
                    saveComp = false;
                    LoggerService.Error($"保存MES日志失败，原因：{ex.Message}", ex);
                }
                return saveComp;
            }
        }

        private static string GetObjCsvStr(object resp)
        {
            return "\"" + JsonConvert.SerializeObject(resp).Replace("\"", "\"\"") + "\"";
        }

        private static string GetObjCsvStr(string resp)
        {
            resp = resp ?? "";
            return "\"" + resp.Replace("\"", "\"\"") + "\"";
        }

        internal static XDocument BuildSoapRequest(string actionName, string requestElementName, Dictionary<string, object> requestParams)
        {
            XNamespace soapNs = "http://schemas.xmlsoap.org/soap/envelope/";
            XNamespace ns = "http://WebXml.com.cn/";
            XNamespace xsd = "http://www.w3.org/2001/XMLSchema";
            XNamespace xmlns = "\"http://WebXml.com.cn/\"";
            XNamespace targetNs = "http://WebXml.com.cn/";
            var soapEnvelope = new XDocument(
                new XElement(soapNs + "Envelope",
                    new XAttribute(XNamespace.Xmlns + "soap", soapNs),
                    new XAttribute(XNamespace.Xmlns + "xsi", ns),
                    new XAttribute(XNamespace.Xmlns + "xsd", xsd),
                    new XElement(soapNs + "Body",
                        new XElement(actionName,
                                requestParams.Select(kvp =>
                                {
                                    if (kvp.Value is IEnumerable<Dictionary<string, object>> list)
                                    {
                                        return new XElement(kvp.Key,
                                            list.Select(item =>
                                                new XElement(kvp.Key.Replace("Array", ""),
                                                    item.Select(subKvp => new XElement(subKvp.Key, subKvp.Value))
                                                )
                                            )
                                        );
                                    }
                                    return new XElement(kvp.Key, kvp.Value);
                                })
                        //)
                        )
                    )
                )
            );
            soapEnvelope.Descendants(actionName).FirstOrDefault().SetAttributeValue("xmlns", xmlns);
            return soapEnvelope;
        }

        public string ParameterVerification(string Ignores = "")
        {
            StringBuilder sb = new StringBuilder();
            if (string.IsNullOrEmpty(Url))
            {
                sb.AppendLine("URL不能为空");
            }
            if (string.IsNullOrEmpty(Site))
            {
                sb.AppendLine("Site不能为空");
            }
            if (string.IsNullOrEmpty(UserName))
            {
                sb.AppendLine("UserName不能为空");
            }
            if (string.IsNullOrEmpty(Password))
            {
                sb.AppendLine("Password不能为空");
            }
            if (!Ignores.Contains("ModeProcessSFC") && string.IsNullOrEmpty(ModeProcessSFC))
            {
                sb.AppendLine("ModeProcessSFC不能为空");
            }
            return sb.ToString();
        }

    }
}
